home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / Caml Light 0.61 / Source / src / runtime / memory.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-24  |  5.2 KB  |  212 lines  |  [TEXT/MPS ]

  1. #include "debugger.h"
  2. #include "fail.h"
  3. #include "freelist.h"
  4. #include "gc.h"
  5. #include "major_gc.h"
  6. #include "memory.h"
  7. #include "minor_gc.h"
  8. #include "misc.h"
  9. #include "mlvalues.h"
  10.  
  11. value *c_roots_head;
  12.  
  13. /* Allocate more memory from malloc for the heap.
  14.    Return a block of at least the requested size (in words).
  15.    Return NULL when out of memory.
  16. */
  17. static char *expand_heap (request)
  18.      mlsize_t request;
  19. {
  20.   char *mem;
  21.   char *new_page_table;
  22.   asize_t new_page_table_size;
  23.   asize_t malloc_request;
  24.   asize_t i, more_pages;
  25.  
  26.   malloc_request = round_heap_chunk_size (Bhsize_wosize (request));
  27.   gc_message ("Growing heap to %ld kB.\n",
  28.           (total_heap_size + malloc_request) / 1024);
  29.   mem = aligned_malloc (malloc_request + sizeof (heap_chunk_head),
  30.                         sizeof (heap_chunk_head));
  31.   if (mem == NULL){
  32.     gc_message ("No room.\n", 0);
  33.     return NULL;
  34.   }
  35.   mem += sizeof (heap_chunk_head);
  36.   (((heap_chunk_head *) mem) [-1]).size = malloc_request;
  37.   Assert (Wosize_bhsize (malloc_request) >= request);
  38.   Hd_hp (mem) = Make_header (Wosize_bhsize (malloc_request), 0, Blue);
  39.  
  40. #ifndef SIXTEEN
  41.   if (mem < heap_start){
  42.     more_pages = -Page (mem);  /* ### page numbers are unsigned ! */
  43.   }else if (Page (mem + malloc_request) > page_table_size){
  44.     Assert (mem >= heap_end);
  45.     more_pages = Page (mem + malloc_request) - page_table_size;
  46.   }else{
  47.     more_pages = 0;
  48.   }
  49.  
  50.   if (more_pages != 0){
  51.     new_page_table_size = page_table_size + more_pages;
  52.     new_page_table = (char *) malloc (new_page_table_size);
  53.     if (new_page_table == NULL){
  54.       gc_message ("no room.\n", 0);
  55.       free (mem);
  56.       return NULL;
  57.     }
  58.   }
  59.  
  60.   if (mem < heap_start){
  61.     Assert (more_pages != 0);
  62.     for (i = 0; i < more_pages; i++){
  63.       new_page_table [i] = Not_in_heap;
  64.     }
  65.     bcopy (page_table, new_page_table + more_pages, page_table_size);
  66.     (((heap_chunk_head *) mem) [-1]).next = heap_start;
  67.     heap_start = mem;
  68.   }else{
  69.     char **last;
  70.     char *cur;
  71.  
  72.     if (mem >= heap_end) heap_end = mem + malloc_request;
  73.     if (more_pages != 0){
  74.       for (i = page_table_size; i < new_page_table_size; i++){
  75.         new_page_table [i] = Not_in_heap;
  76.       }
  77.       bcopy (page_table, new_page_table, page_table_size);
  78.     }
  79.     last = &heap_start;
  80.     cur = *last;
  81.     while (cur != NULL && cur < mem){
  82.       last = &((((heap_chunk_head *) cur) [-1]).next);
  83.       cur = *last;
  84.     }
  85.     (((heap_chunk_head *) mem) [-1]).next = cur;
  86.     *last = mem;
  87.   }
  88.  
  89.   if (more_pages != 0){
  90.     free (page_table);
  91.     page_table = new_page_table;
  92.     page_table_size = new_page_table_size;
  93.   }
  94. #else                           /* Simplified version for the 8086 */
  95.   {
  96.     char **last;
  97.     char *cur;
  98.  
  99.     last = &heap_start;
  100.     cur = *last;
  101.     while (cur != NULL && (char huge *) cur < (char huge *) mem){
  102.       last = &((((heap_chunk_head *) cur) [-1]).next);
  103.       cur = *last;
  104.     }
  105.     (((heap_chunk_head *) mem) [-1]).next = cur;
  106.     *last = mem;
  107.   }
  108. #endif
  109.  
  110.   for (i = Page (mem); i < Page (mem + malloc_request); i++){
  111.     page_table [i] = In_heap;
  112.   }
  113.   total_heap_size += malloc_request;
  114.   return Bp_hp (mem);
  115. }
  116.  
  117. value raw_alloc_shr (wosize, tag)
  118.      mlsize_t wosize;
  119.      tag_t tag;
  120. {
  121.   char *hp, *new_block;
  122.  
  123.   while (1){
  124.     hp = fl_allocate (master_fl, wosize);
  125.     if (hp != NULL) break;
  126.     new_block = expand_heap (wosize);
  127.     if (new_block == NULL) raise_out_of_memory ();
  128.     fl_add_block (master_fl, new_block);
  129.   }
  130.   Assert (Is_in_heap (Val_hp (hp)));
  131.  
  132.   if (gc_phase == Phase_mark || (addr)hp >= (addr)gc_sweep_hp){
  133.     Hd_hp (hp) = Make_header (wosize, tag, Black);
  134.   }else{
  135.     Hd_hp (hp) = Make_header (wosize, tag, White);
  136.   }
  137.   allocated_words += Whsize_wosize (wosize);
  138.   return Val_hp (hp);
  139. }
  140.  
  141. value alloc_shr (wosize, tag)
  142.      mlsize_t wosize;
  143.      tag_t tag;
  144. {
  145.   if (allocated_words > Wsize_bsize (young_end - young_start)) {
  146.     minor_collection ();
  147.   }
  148.   return raw_alloc_shr (wosize, tag);
  149. }
  150.  
  151. /* You must use [initialize] to store the initial value in a field of
  152.    a shared block, unless you are sure the value is not a young block.
  153.    A block value [v] is a shared block if and only if [Is_in_heap (v)]
  154.    is true.
  155. */
  156. /* [initialize] never calls the GC, so you may call it while an object is
  157.    unfinished (i.e. just after a call to [alloc_shr].) */
  158. void initialize (fp, val)
  159.      value *fp;
  160.      value val;
  161. {
  162.   *fp = val;
  163.   Assert (Is_in_heap (fp));
  164.   if (Is_block (val) && Is_young (val)){
  165.     *ref_table_ptr++ = fp;
  166.     if (ref_table_ptr >= ref_table_end){
  167.       realloc_ref_table ();
  168.     }
  169.   }
  170. }
  171.  
  172. /* You must use [modify] to change a field of an existing shared block,
  173.    unless you are sure the value being overwritten is not a shared block and
  174.    the value being written is not a young block. */
  175. /* [modify] never calls the GC. */
  176. void modify (fp, val)
  177.      value *fp;
  178.      value val;
  179. {
  180.   Modify (fp, val);
  181. }
  182.  
  183. char * stat_alloc (sz)
  184.      asize_t sz;
  185. {
  186.   char * result = (char *) malloc (sz);
  187.  
  188.   if (result == NULL) raise_out_of_memory ();
  189.   return result;
  190. }
  191.  
  192. void stat_free (blk)
  193.      char * blk;
  194. {
  195.   free (blk);
  196. }
  197.  
  198. char * stat_resize (blk, sz)
  199.      char *blk;
  200.      asize_t sz;
  201. {
  202.   return (char *) realloc (blk, sz);
  203. }
  204.  
  205. void init_memory (generation_size, heap_size)
  206.      asize_t generation_size, heap_size;
  207. {
  208.   init_minor_heap (generation_size);
  209.   init_major_heap (heap_size);
  210.   c_roots_head = NULL;
  211. }
  212.